import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONType;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fasteat.common.util.FileUtil;
import com.fasteat.menu.FastEatMenuApplication;
import com.fasteat.menu.entity.Category;
import com.fasteat.menu.mapper.CategoryMapper;
import com.fasteat.menu.mapper.MenuMapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author run
 * @since 2021/3/8 22:06
 */
@SpringBootTest(classes = FastEatMenuApplication.class)
@RunWith(SpringRunner.class)
public class JsoupTest {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Test
    public void test(){
        List<String> titles = menuMapper.getTitle();
//        List<String> titles = new ArrayList<>();
//        titles.add("糖醋排骨");
        titles.forEach((title)->{
            System.out.println(title);
            try {
                Connection connect = Jsoup.connect("https://www.xiachufang.com/search/?keyword=" + title);
                Element body = connect.get().body();
                String menuUrl = body.getElementsByClass("info pure-u")
                        .get(0)
                        .getElementsByTag("p")
                        .get(0)
                        .getElementsByTag("a")
                        .get(0)
                        .attr("href");
                Connection menuConnect = Jsoup.connect("https://www.xiachufang.com" + menuUrl);
                Elements containers = menuConnect.get()
                                        .body()
                                        .getElementsByClass("steps")
                                        .get(0)
                                        .getElementsByClass("container");
                int index = 0;
                List<MenuStep> menuSteps = new ArrayList<>();
                for (Element container : containers) {
                    try {
                        String stepContext = container.getElementsByClass("text").get(0).text();
                        String imgUrl = container.getElementsByTag("img").get(0).attr("src");
                        MultipartFile multipartFile = urlToMultipartFile(imgUrl);
                        imgUrl = ((String) JSONObject.parseObject(FileUtil.upload(multipartFile)).get("url"));
                        menuSteps.add(new MenuStep(imgUrl,stepContext,++index));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                String menuContext = JSON.toJSONString(menuSteps);
                menuMapper.setMenuContextByTitle(menuContext,title);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @JSONType(orders = {"url","value","sIndex"})
    class MenuStep{
        private String url;
        private String value;
        private Integer sIndex;

        public MenuStep(String url, String value, Integer sIndex) {
            this.url = url;
            this.value = value;
            this.sIndex = sIndex;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public Integer getsIndex() {
            return sIndex;
        }

        public void setsIndex(Integer sIndex) {
            this.sIndex = sIndex;
        }
    }


    public static File inputStreamToFile(InputStream ins, String name) throws Exception{
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }

    /**
     * file转multipartFile
     */
    public static MultipartFile fileToMultipartFile(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item=factory.createItem(file.getName(),"text/plain",true,file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }

    /**
     * url转MultipartFile
     */
    public static MultipartFile urlToMultipartFile(String url) throws Exception {
        File file = null;
        MultipartFile multipartFile = null;
        try {
            HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection();
            httpUrl.connect();
            file = inputStreamToFile(httpUrl.getInputStream(), IdWorker.get32UUID() + ".png");

            multipartFile = fileToMultipartFile(file);
            httpUrl.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return multipartFile;
    }


    @Test
    public void getCategory() throws Exception{
        Element body = Jsoup.connect("https://mip.xiachufang.com/category/").get().body();
        Elements sections = body.getElementById("site-body").children();
        sections.forEach((section)->{
            String rootName = section.getElementsByTag("h3").get(0).text();
            Category rootCategory = new Category();
            rootCategory.setCategoryName(rootName);
            categoryMapper.insert(rootCategory);
            String rootId = rootCategory.getId();
            Elements categories = section.getElementsByTag("a");
            categories.forEach((category)->{
                String cover = category.getElementsByClass("cover").get(0).attr("src");
                String name = category.getElementsByClass("name").get(0).text();
                try {
                    MultipartFile multipartFile = urlToMultipartFile(cover);
                    cover = (String) (JSON.parseObject(FileUtil.upload(multipartFile)).get("url"));
                } catch (Exception e) {
                    e.printStackTrace();
                }

                Category child = new Category();
                child.setParentId(rootId);
                child.setCategoryCover(cover);
                child.setCategoryName(name);
                categoryMapper.insert(child);
            });
        });
    }

}
